#pragma once

#include <iostream>
#include <memory>
#include <mutex>
#include <type_traits>
#include <utility>
#include <type_traits>
#include <iostream>
#include <base/macros.h>

DEFINE_TYPE_TRAIT(HasLess, operator<)  // NOLINT

template <class Value, class End>
typename std::enable_if<HasLess<Value>::value && HasLess<End>::value,
                        bool>::type
LessThan(const Value& val, const End& end) {
  return val < end;
}

template <class Value, class End>
typename std::enable_if<!HasLess<Value>::value || !HasLess<End>::value,
                        bool>::type
LessThan(const Value& val, const End& end) {
  return val != end;
}


#define FOR_EACH(i, begin, end)           \
  for (auto i = (true ? (begin) : (end)); \
       LessThan(i, (end)); ++i)




DEFINE_TYPE_TRAIT(HasShutdown, Shutdown)

template <typename T>
typename std::enable_if<HasShutdown<T>::value>::type CallShutdown(T *instance){
    instance->Shutdown();
}

template <typename T>
typename std::enable_if<!HasShutdown<T>::value>::type CallShutdown(T *instance){
    (void)instance;
}


#undef UNUSED
#undef DISALLOW_COPY_AND_ASSIGN

#define UNUSED(param)  (void)param

/*禁用拷贝构造和 = 赋值*/
#define DISALLOW_COPY_AND_ASSIGN(classname) \
  classname(const classname &) = delete;    \
  classname &operator=(const classname &) = delete;

/*利用 std::once_flag 和 std::call_once 实现的线程安全的单例宏*/
#define DECLARE_SINGLETON(classname)                                      \
 public:                                                                  \
  static classname *Instance(bool create_if_needed = true) {              \
    static classname *instance = nullptr;                                 \
    if (!instance && create_if_needed) {                                  \
      static std::once_flag flag;                                         \
      std::call_once(flag,                                                \
                     [&] { instance = new (std::nothrow) classname(); }); \
    }                                                                     \
    return instance;                                                      \
  }                                                                       \
                                                                          \
  static void CleanUp() {                                                 \
    auto instance = Instance(false);                                      \
    if (instance != nullptr) {                                            \
      CallShutdown(instance);                                             \
    }                                                                     \
  }                                                                       \
                                                                          \
 private:                                                                 \
  classname();                                                            \
  DISALLOW_COPY_AND_ASSIGN(classname)



/*
  std::hash<std::string>{} ： 创建一个 std::hash<std::string>的临时对象 { } 是初始化列表 ， std::hash<std::string> 内部重载了()
  获取一个字符串的哈希值
*/
inline std::size_t Hash(const std::string& key) {
    return std::hash<std::string>{}(key);
  }